<?php

/**
 * Model类 Yjnic_Model
 * 模仿 TP的操作
 *
 * @author prettyyjnic <prettyyjnic@qq.com> 20151027
 */
class Yjnic_Model {

    protected $_select_sql  = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%WHERE%%ORDER%%LIMIT%';

    protected $_pdo = NULL;
    protected $_order = '';
    protected $_table = '';
    protected $_distinct = false;
    protected $_limit = '';
    protected $_where =  '';
    protected $_fields = '*';
    protected $_where_params = array();
    protected $_params = array();
    protected $_prefix = '';
    protected $_configs = array();

    public function __construct($configs=null){
        if (empty($configs)) {          
            $configs = DI()->config->get('dbs.servers.default');
        }
        if (empty($configs)) {
            throw new Yjnic_Exception("DB CONFIGS ERROR", 501);            
        }
        $this->_configs = $configs;
        $this->_prefix = $configs['prefix'];
        $this->_pdo = Yjnic_Db_Factory::getInstance($this->_configs);
    }

    /**
     * 分页查询
     * @param $sql 要查询的sql
     * @param $params sql参数
     * @param $page 页数
     * @param $page_size 每页多少
     * @return $ret['total'] 总数
     * @return $ret['total_page'] 总页数
     * @return $ret['current_page'] 当前页数
     * @return $ret['rows'] 数据
     */
    public function pageQuery($sql='', $params=array(), $page=1, $page_size=10) {
        if ($sql =='') {
            $sql = $this->_parseSelectSql();$params=$this->_params();
        }
        $ret = array();
        $total_sql = "SELECT COUNT(*) AS counts ".substr($sql, stripos($sql,'from'), strlen($sql));
        $ret['total'] = $this->getOne($total_sql, $params);
        $ret['total_page'] = ceil($ret['total'] / $page_size);
        $ret['current_page'] = $page;       
        $sql .= ' LIMIT ' . intval( ($page-1) * $page_size ).',' . intval($page_size);
        $ret['rows'] = $this->fetchAll($sql, $params);
        return $ret;
    }

    /**
     * 设置table前缀
     */
    public function tablePrefix($table_prefix){
        $this->_prefix = $table_prefix; return $this;
    }

    /**
     * table 方法
     */
    public function table($table_name){
        $this->_table = $this->_prefix . $table_name; return $this;
    }

    /**
     * order
     */
    public function order($order){
        $this->_order = ' ORDER BY '. $order;
        return $this;
    }

    /**
     * where 方法
     */
    public function where(){
        $args_nums = func_num_args();
        $args = func_get_args();
        if ($args_nums == 1) {// 只有一个参数
            $this->_where = $args[0];
            $this->_where_params = array();
        }elseif($args_nums==2&&is_array($args[1])){//第二个参数为数组
            $this->_where = $args[0];
            unset($args[0]);
            $this->_where_params = $args[1];
        }else{
            $this->_where = $args[0];
            unset($args[0]);
            $this->_where_params = $args;
        }
        return $this;
    }

    /**
     * 设置要获取的字段
     */
    public function fields($fields){
        if (is_array($fields)) {
            $fields = implode(',', $fields);
        }
        $this->_fields = $fields;return $this;
    }

    public function distinct($distinct=true){
        $this->_distinct = $distinct; return $this;
    }

    public function limit($start, $end=false){
        if ($end == false) {
            $this->_limit = ' LIMIT '. intval($start);
        }else{
            $this->_limit = ' LIMIT '. intval($start) . ','. intval($end);
        }
        return $this;
    }

    /**
     * select 出结果集
     */
    public function select(){    
        $sql = $this->_parseSelectSql();        
        $ret = $this->_pdo->fetchAll($sql, $this->_params);
        $this->_reset();
        return $ret;
    }

    public function selectRow(){
        $sql = $this->_parseSelectSql();
        $ret = $this->_pdo->fetchRow($sql, $this->_params);
        $this->_reset();
        return $ret;
    }

    public function findAll($field){
        $sql = $this->_parseSelectSql();
        $ret = $this->_pdo->getAll($sql, $field, $this->_params);
        $this->_reset();
        return $ret;
    }

    public function findRow($field){
        $sql = $this->_parseSelectSql();
        $ret = $this->_pdo->getRow($sql, $field, $this->_params);
        $this->_reset();
        return $ret;
    }

    public function findOne($field){
        $this->_fields = $field;
        $sql = $this->_parseSelectSql();
        $ret = $this->_pdo->getOne($sql, $this->_params);
        $this->_reset();
        return $ret;
    }

    public function save($data){
        if (!empty($this->_where_params)) {
            $where = array();
            $where[0] = $this->_where; $where[1] = $this->_where_params;
        }else{
            $where = $this->_where;
        }
        $ret = $this->_pdo->update($data, $where, $this->_table);
        $this->_reset();
        return $ret;
    }

    public function insert($data){
        return $this->_pdo->insert($data, $this->_table);
    }

    public function delete(){
        if (!empty($this->_where_params)) {
            $where = array();
            $where[0] = $this->_where; $where[1] = $this->_where_params;
        }else{
            $where = $this->_where;
        }
        $ret = $this->_pdo->delete($where, $this->_table);
        $this->_reset();
        return $ret;
    }

    protected function _parseWhere(){
        if ($this->_where) {
            $condition = ' WHERE '.$this->_where; $this->_params = array_merge($this->_params, $this->_where_params);
        }else{
            $condition = '';
        }
        return $condition;
    }

    protected function _parseSelectSql(){
        $distinct = '';
        if ($this->_distinct) { $distinct = ' DISTINCT'; }
        $sql = str_replace(
            array('%TABLE%','%DISTINCT%','%FIELD%','%WHERE%','%LIMIT%', '%ORDER%'),
            array(
                $this->_table,
                $distinct ? ' DISTINCT' : '',
                $this->_fields,
                $this->_parseWhere(),
                $this->_limit,
                $this->_order,       
            ),$this->_select_sql);
        return $sql;
    }

    /**
     * reset 所有条件
     */
    protected function _reset(){
        $this->_fields = '*';
        $this->_order = '';
        $this->_limit = '';
        $this->_where = '';
        $this->_params = array();
        $this->_where_params = array();
    }

    /**
     * 
     */
    
    public function __call($method, $args){         
        return call_user_func_array(array($this->_pdo, $method), $args);
    }
}